package config

import (
	"github.com/spf13/cast"
	viperlib "github.com/spf13/viper" // 自定义包名，避免与内置 viper 实例冲突
	"time"
)

type ConfigFunc func() map[string]interface{}

var ConfigFuncs map[string]ConfigFunc
var viper *viperlib.Viper

func init() {
	ConfigFuncs = make(map[string]ConfigFunc)
}
func InitConfig(confDir string, envSuffix string) {
	viper = viperlib.New()
	viper.AddConfigPath(confDir)
	viper.SetConfigName(envSuffix)
	viper.SetConfigType("yaml")
	viper.SetEnvPrefix("appenv")
	if err := viper.ReadInConfig(); err != nil {
		panic(any(err))
	}
	viper.WatchConfig()
	loadConfig()
}
func loadConfig() {
	for name, fn := range ConfigFuncs {
		viper.Set(name, fn())
	}
}

func Get(path string, defaultValue ...interface{}) string {
	return GetString(path, defaultValue)
}
func Env(key string, defaultValue ...interface{}) interface{} {
	if len(defaultValue) > 0 {
		return internalGet(key, defaultValue[0])
	}
	return internalGet(key)
}
func Add(name string, configFn ConfigFunc) {
	ConfigFuncs[name] = configFn
}
func internalGet(key string, defaultValue ...interface{}) interface{} {
	if !viper.IsSet(key) {
		if len(defaultValue) > 0 {
			return defaultValue[0]
		}
		return nil
	}
	return viper.Get(key)
}

// GetString 获取 String 类型的配置信息
func GetString(key string, defaultValue ...interface{}) string {
	return cast.ToString(internalGet(key, defaultValue...))
}

// GetInt 获取 Int 类型的配置信息
func GetInt(key string, defaultValue ...interface{}) int {
	return cast.ToInt(internalGet(key, defaultValue...))
}

// GetFloat64 获取 float64 类型的配置信息
func GetFloat64(key string, defaultValue ...interface{}) float64 {
	return cast.ToFloat64(internalGet(key, defaultValue...))
}
func GetFloat32(key string, defaultValue ...interface{}) float32 {
	return cast.ToFloat32(internalGet(key, defaultValue...))
}

// GetInt64 获取 Int64 类型的配置信息
func GetInt64(key string, defaultValue ...interface{}) int64 {
	return cast.ToInt64(internalGet(key, defaultValue...))
}

// GetUint 获取 Uint 类型的配置信息
func GetUint(key string, defaultValue ...interface{}) uint {
	return cast.ToUint(internalGet(key, defaultValue...))
}

// GetBool 获取 Bool 类型的配置信息
func GetBool(key string, defaultValue ...interface{}) bool {
	return cast.ToBool(internalGet(key, defaultValue...))
}

// GetStringMapString 获取结构数据
func GetStringMapString(key string) map[string]string {
	return viper.GetStringMapString(key)
}
func GetDuration(key string) time.Duration {
	return viper.GetDuration(key)
}
func GetStringMap(key string) map[string]interface{} {
	return viper.GetStringMap(key)
}
